﻿using BomComparison.Core.Interface;
using BomComparison.Core.Model;

namespace BomComparison.Algorithm.Comparers;

public class CompareByPartReference : IBomComparisonService
{
    public ComparisonResult Result { get; private set; } = new ComparisonResult();
    public ComparisonResult CompareBoms(List<BomItem> sourceBom,
                                  List<BomItem> targetBom)
    {


        // 使用 createRefDict 函数创建旧 BOM 和新 BOM 的字典
        var oldRefDict = CreateReferenceDictionary(sourceBom);
        var newRefDict = CreateReferenceDictionary(targetBom);

        // 获取旧 BOM 和新 BOM 的所有位号集合
        var oldRefs = oldRefDict.Keys;
        var newRefs = newRefDict.Keys;

        // 1、新增位号处理：
        // 找出新 BOM 中存在但旧 BOM 中不存在的位号对应的 BomItem，并添加到结果中
        var newOnlyRefs = newRefs.Except(oldRefs).ToList();

        foreach (var refDes in newOnlyRefs)
        {
            Result.SummaryByPartReferences.Add(new ComparisonResultByPartReference
            {
                PartReference = refDes,
                OldBomItem = null,
                NewBomItem = newRefDict[refDes],
                ChangeType = PartReferenceChangeType.Added
            });
        }

        // 2、删除位号处理：
        // 找出旧 BOM 中存在但新 BOM 中不存在的位号对应的 BomItem，并添加到结果中
        var oldOnlyRefs = oldRefs.Except(newRefs).ToList();

        foreach (var refDes in oldOnlyRefs)
        {
            Result.SummaryByPartReferences.Add(new ComparisonResultByPartReference
            {
                PartReference = refDes,
                OldBomItem = oldRefDict[refDes],
                ChangeType = PartReferenceChangeType.Deleted
            });
        }

        // 3、替代位号处理：
        // 找出位号相同但料号不同的 BomItem（Replaced）
        var commonRefs = oldRefs.Intersect(newRefs).ToList();

        var replacements = new List<ComparisonResultByPartReference>();
        foreach (var refDes in commonRefs)
        {
            if (oldRefDict[refDes].PartNumber != newRefDict[refDes].PartNumber)
            {
                replacements.Add(new ComparisonResultByPartReference
                {
                    PartReference = refDes,
                    OldBomItem = oldRefDict[refDes],
                    NewBomItem = newRefDict[refDes],
                    ChangeType = PartReferenceChangeType.Replaced
                });
            }
        }

        Result.SummaryByPartReferences.AddRange(replacements);

        return Result;
    }
    
    // 定义一个函数来创建字典，键为位号，值为对应的 BomItem 对象

    private Dictionary<string, BomItem> CreateReferenceDictionary(List<BomItem> bom)
    {
        ArgumentNullException.ThrowIfNull(bom);

        var dictionary = new Dictionary<string, BomItem>();

        foreach (var item in bom)
        {
            if (item == null || string.IsNullOrWhiteSpace(item.PartReference))
            {
                continue; // 跳过无效项
            }

            List<string> refDesList = PartReferenceParser.StringToList(item.PartReference);
            if (refDesList == null)
            {
                continue; // 防止 NullReferenceException
            }

            foreach (var refDes in refDesList)
            {
                if (!string.IsNullOrWhiteSpace(refDes))
                {
                    // 处理键冲突：保留第一个或最后一个出现的项
                    // 此处示例为保留第一个，可根据业务需求调整
                    if (!dictionary.ContainsKey(refDes))
                    {
                        dictionary[refDes] = item;
                    }
                }
            }
        }

        return dictionary;
    }
}
